/*
 * Scene.h
 *
 *  Created on: 2 Nov 2012
 *      Author: guy
 */

#ifndef SCENE_H_
#define SCENE_H_

#include <tr1/memory>
#include <memory>
#include <string>
#include <set>
#include "core/GameObject.h"
#include "types/Image.h"
#include "types/Vector2D.h"
#include "types/Rect.h"
#include "core/Screen.h"
#include "components/Collider.h"

namespace SolidityEngine {


class Scene;
typedef std::unique_ptr<Scene> Scene_ptr;


class Scene: public Object {
	std::list<GameObject_ptr> _objects;
	Image* _backdrop;
	Vector2D _size;
    std::list<Renderer*> _renderscenelist;
    std::list<Renderer*> _renderscreenlist;
	std::list<Collider*> _colliderlist;
	SDL_mutex* _renderlist_mutex;

public:
	Scene(const std::string& name = "default", int width = 800, int height = 600);
	Scene(const Scene&);
	GameObject* AddObject(const std::string& = "empty"); //create an empty object in the scene
	void AddObject(GameObject* object);
    void DeleteObject(GameObject* object);

	void SetBackdropImage(Image* img);

	Image* GetBackdropImage();
	const Image* GetBackdropImage() const;

    std::list<int> GetObjectIDs();
    std::list<int> GetObjectIDs() const;

    GameObject* GetObject(int ID);

    Vector2D GetSize() {return _size;};
    Vector2D GetSize() const {return _size;};

    //render the scene onto a surface and return it.
    std::shared_ptr<SDL_Surface> GetFrame();

    void Update();

    //render any screen-space stuff on the given surface
    void RenderScreen(SDL_Surface* surface);



private:
    std::string _Serialize(){
        return std::string("Serialization not implemented for: ")+std::string(typeid(*this).name());
    };

    virtual Scene* _Clone();

    void _DetectCollisions();

    std::shared_ptr<SDL_Surface> _RenderScene();

    void _BuildLists();

};

} /* namespace SolidCore */
#endif /* SCENE_H_ */
